package com.recipedb.recipedb.service.impl;

import com.recipedb.recipedb.entity.UserBrowse;
import com.recipedb.recipedb.entity.User;
import com.recipedb.recipedb.entity.Recipe;
import com.recipedb.recipedb.repository.UserBrowseRepository;
import com.recipedb.recipedb.service.UserBrowseService;
import com.recipedb.recipedb.service.UserService;
import com.recipedb.recipedb.service.RecipeService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;

import java.util.ArrayList;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class UserBrowseServiceImpl implements UserBrowseService {

    private final UserBrowseRepository userBrowseRepository;
    private final UserService userService;
    private final RecipeService recipeService;

    @Override
    @Transactional
    public UserBrowse createBrowseRecord(Long userId, Long recipeId) {
        User user = userService.findById(userId)
                .orElseThrow(() -> new RuntimeException("用户不存在"));

        Optional<UserBrowse> existingRecord = userBrowseRepository.findByUserIdAndRecipeId(userId, recipeId);
        if (existingRecord.isPresent()) {
            // 如果已存在，更新创建时间
            UserBrowse record = existingRecord.get();
            record.setCreatedAt(LocalDateTime.now());
            UserBrowse savedRecord = userBrowseRepository.save(record);
            recipeService.findById(record.getRecipeId()).ifPresent(savedRecord::setRecipe);
            return savedRecord;
        }

        // 创建新的浏览记录
        UserBrowse browseRecord = new UserBrowse();
        browseRecord.setUser(user);
        browseRecord.setRecipeId(recipeId);
        browseRecord.setCreatedAt(LocalDateTime.now());

        UserBrowse savedRecord = userBrowseRepository.save(browseRecord);
        // 设置菜谱实体
        recipeService.findById(recipeId).ifPresent(savedRecord::setRecipe);
        return savedRecord;
    }


    @Override
    public List<UserBrowse> getBrowseRecordsByUserId(Long userId) {
        List<UserBrowse> browseRecords = userBrowseRepository.findByUserIdOrderByCreatedAtDesc(userId);
        enrichBrowseRecordsWithRecipe(browseRecords);
        return browseRecords;
    }

    @Override
    public List<UserBrowse> getAllBrowseRecords() {
        List<UserBrowse> browseRecords = userBrowseRepository.findAllByOrderByCreatedAtDesc();
        enrichBrowseRecordsWithRecipe(browseRecords);
        return browseRecords;
    }

    @Override
    @Transactional
    public boolean deleteBrowseRecord(Long id, Long userId) {
        int deletedCount = userBrowseRepository.deleteByIdAndUserId(id, userId);
        return deletedCount > 0;
    }

    /**
     * 获取单条浏览记录详情（包含完整菜谱信息）
     */
    @Override
    public Optional<UserBrowse> getBrowseRecordById(Long id) {
        Optional<UserBrowse> browseRecord = userBrowseRepository.findById(id);
        browseRecord.ifPresent(record -> {
            recipeService.findById(record.getRecipeId()).ifPresent(record::setRecipe);
        });
        return browseRecord;
    }

    /**
     * 根据用户ID和菜谱ID获取浏览记录（包含完整菜谱信息）
     */
    @Override
    public Optional<UserBrowse> getBrowseRecordByUserIdAndRecipeId(Long userId, Long recipeId) {
        Optional<UserBrowse> browseRecord = userBrowseRepository.findByUserIdAndRecipeId(userId, recipeId);
        browseRecord.ifPresent(record -> {
            recipeService.findById(record.getRecipeId()).ifPresent(record::setRecipe);
        });
        return browseRecord;
    }


    @Override
    public List<Recipe> getRecipesByUserId(Long userId) {
        List<UserBrowse> browseRecords = userBrowseRepository.findByUserIdOrderByCreatedAtDesc(userId);
        return browseRecords.stream()
                .map(browse -> recipeService.findById(browse.getRecipeId()))
                .filter(Optional::isPresent)
                .map(Optional::get)
                .collect(Collectors.toList());
    }


    private void enrichBrowseRecordsWithRecipe(List<UserBrowse> browseRecords) {
        browseRecords.forEach(record -> {
            recipeService.findById(record.getRecipeId()).ifPresent(record::setRecipe);
        });
    }


    // ========== 核心：浏览记录搜索接口（和收藏逻辑完全对齐） ==========
    @Override
    public Page<UserBrowse> searchBrowseRecords(
            Long userId,
            String keyword,
            String tag,
            String category,
            String ingredient,
            Integer pageNum,
            Integer pageSize) {

        // 1. 参数兜底（页码从0开始，前端传1对应第0页）
        int page = pageNum == null || pageNum < 1 ? 0 : pageNum - 1;
        int size = pageSize == null || pageSize < 1 ? 10 : pageSize;

        // 2. 步骤1：查询用户所有浏览记录
        List<UserBrowse> allUserBrowses = userBrowseRepository.findByUserIdOrderByCreatedAtDesc(userId);
        if (allUserBrowses.isEmpty()) {
            return new PageImpl<>(new ArrayList<>(), PageRequest.of(page, size), 0);
        }

        // 3. 步骤2：复用 RecipeService 的 search 方法，获取符合条件的菜谱列表
        List<Recipe> filteredRecipes = recipeService.search(keyword, tag, category, ingredient);
        if (filteredRecipes.isEmpty()) {
            return new PageImpl<>(new ArrayList<>(), PageRequest.of(page, size), 0);
        }
        // 提取符合条件的菜谱ID
        List<Long> targetRecipeIds = filteredRecipes.stream()
                .map(Recipe::getId)
                .collect(Collectors.toList());

        // 4. 步骤3：筛选用户浏览记录中包含这些菜谱ID的记录
        List<UserBrowse> filteredBrowses = allUserBrowses.stream()
                .filter(browse -> targetRecipeIds.contains(browse.getRecipeId()))
                .collect(Collectors.toList());

        // 5. 步骤4：手动分页
        int startIndex = page * size;
        int endIndex = Math.min(startIndex + size, filteredBrowses.size());
        List<UserBrowse> pagedBrowses = startIndex >= filteredBrowses.size()
                ? new ArrayList<>()
                : filteredBrowses.subList(startIndex, endIndex);

        // 6. 步骤5：填充菜谱信息（含收藏数等完整信息）
        pagedBrowses.forEach(browse -> {
            recipeService.findById(browse.getRecipeId())
                    .map(recipeService::setFavoriteCountForRecipe) // 复用菜谱收藏数设置逻辑
                    .ifPresent(browse::setRecipe);
        });

        // 7. 封装 Page 对象返回
        return new PageImpl<>(
                pagedBrowses,
                PageRequest.of(page, size),
                filteredBrowses.size()
        );
    }


}